var WBT = function (obj) {
    /*
    websocket接口地址
    1、http请求还是https请求 前缀不一样
	2、ip地址host
    3、端口号
    */
    const config = obj ? obj : {}
    const protocol = (window.location.protocol == 'http:') ? 'ws://' : 'wss://';
    const host =  "localhost:";
    const port = 7397;
    const uid = $("#userId").val();
    //接口地址url
    this.url = config.ip || protocol + host + port + "?userId=" + uid;
    //socket对象
    this.socket;
    //自定义Ws连接函数：服务器连接成功
    this.onopen = function(e){
        console.log(e)
    };
    //自定义Ws消息接收函数：服务器向前端推送消息时触发
    this.onmessage = function(e){
        //处理各种推送消息
        this.handleEvent(e.data)
    };
    //自定义Ws异常事件：Ws报错后触发
    this.onerror = function(e){
        console.log('error')
    }
    //自定义Ws关闭事件：Ws连接关闭后触发
    this.onclose = function (e) {
        console.log('close')
    },
    //初始化websocket连接
    this.initWs()
}

//初始化websocket连接
WBT.prototype.initWs = function () {
    window.WebSocket = window.WebSocket || window.MozWebSocket;

    var $reConnectDiv = $('body');
    var errorCount = 1;
    var MAX_CONNECT = 30; //最大尝试重连次数

    if (!window.WebSocket) { // 检测浏览器支持
        console.error('错误: 浏览器不支持websocket');
        return;
    }
    var that = this;
    //自动重连
    this.socket = new ReconnectingWebSocket(this.url); // 创建连接并注册响应函数
    this.socket.onopen = function (e) {
        if (errorCount > 1) {
            //刷新页面
            window.location.reload();
        }
        that.onopen(e);
    };
    this.socket.onmessage = function (e) {
        that.onmessage(e);
    };
    this.socket.onclose = function (e) {
        that.onclose(e);
        that.socket = null; // 清理
        onLostContenting(event);
    };
    this.socket.onerror = function (e) {
        that.onerror(e);
        onLostContenting(event);
    }

    function onLostContenting(event) {
        console.log(event);
        if (errorCount >= MAX_CONNECT) {
            window.location.reload();
        }
        $reConnectDiv.loaded();
        $reConnectDiv.loading("与服务器失去连接，正在尝试第（" + errorCount + "/" + MAX_CONNECT + "）次连接...");
        errorCount++;
    }

    return this;
}

//监听消息的处理函数集合。
MESSAGE_HANDLERS = {};
LINTTYPE_CODE_MAP = {};

/**
 * 全局方法 监听服务器消息
 * @param type 消息类型，可以是数组
 * @param handler 该类型消息的处理方式
 */
function watchMessage(type, handler) {
    if ($.isArray(type)) {
        for (var i = 0; i < type.length; i++) {
            var code = type[i].code;
            putLinkTypeCodeMap(code, type[i])
            registerTypeHandler(code, handler)
        }
    } else {
        putLinkTypeCodeMap(type.code, type)
        registerTypeHandler(type.code, handler)
    }
}

/**
 * 对code进行处理
 * @param code
 * @param linkType
 */
function putLinkTypeCodeMap(code, linkType) {
    if (!LINTTYPE_CODE_MAP[code]) {
        LINTTYPE_CODE_MAP[code] = linkType
    }
}

/**
 * 注册监听
 * @param typeCode
 * @param handler
 */
function registerTypeHandler(typeCode, handler) {
    var messageHandler = MESSAGE_HANDLERS[typeCode];
    if (messageHandler) {
        if (!$.isArray(messageHandler)) {
            var handlers = [];
            handlers.push(messageHandler)
            messageHandler = handlers
        }
        messageHandler.push(handler)
        MESSAGE_HANDLERS[typeCode] = messageHandler
    } else {
        var handlers = [];
        handlers.push(handler)
        MESSAGE_HANDLERS[typeCode] = handlers
    }
}

/**
 * 处理事件
 */
WBT.prototype.handleEvent = function (msg) {
    msg = $.parseJSON(msg);
    if ($.isArray(msg)) {
        $.each(msg, function (j, m) {
            handleMsg(m);
        })
    } else {
        handleMsg(msg);
    }
}

/**
 * 消息处理
 * @param msg
 */
var handleMsg = function (msg) {
    var handandlers = MESSAGE_HANDLERS[msg.linkType.code];
    if (msg.linkType && handandlers) {
        $.each(handandlers, function (i, handler) {
            var linkData = msg.linkData;
            if (linkData) {
                linkData = linkData.replace(new RegExp('&quot;',"gm"),"\"");
                msg.linkData = $.parseJSON(linkData)
            }

            if (handler) {
                //后台的linkType不一定有tabTitle。
                msg.linkType = LINTTYPE_CODE_MAP[msg.linkType.code]
                handler(msg, msg.linkType);
            }
        })
    }
}

//发送参数
let defaultParam = {
    userId: null,
    params:{}
}

//发送方法
WBT.prototype.send = function (params) {
    let param = defaultParam;
    param.userId = $("#userId").val();
    param.params = params;
    //组装json数据
    this.socket.send(JSON.stringify(param))
}